package main

import (
    "fmt"
    "flag"
    "bufio"
    "os"
    "time"
    "strconv"
    "io"
    "algorithms/qsort"
    "algorithms/bubblesort"
)

var infile *string = flag.String("i", "infile", "File contains values for sorting")
var outfile *string = flag.String("o", "outfile", "File to receive sort value")
var algorithm *string = flag.String("a", "qsort", "sort algorithm")

func readValues(infile string) (values []int, err error) {
    file, err := os.Open(infile)
    if err != nil {
        fmt.Println("Fail to open file ", infile);
        return
    }

    defer file.Close()

    br := bufio.NewReader(file)

    values = make([]int, 0)

    for {
        line, isPrefix, err1 := br.ReadLine()

        if err1 != nil {
            if err1 != io.EOF {
                err = err1
            }
            break
        }

        if isPrefix {
            fmt.Println("A too long line, seems unexpected.");
            return
        }

        str := string(line)

        value, err1 := strconv.Atoi(str)

        if err1 != nil {
            err = err1
            return
        }

        values = append(values, value)
    }
    return
}

func writeValues(values []int, outfile string) error {
    file, err := os.Create(outfile)

     if err != nil {
         fmt.Println("Fail to Create ", outfile)
         return err
     }

     defer file.Close()

     for _, value := range values {
        str := strconv.Itoa(value)
        file.WriteString(str + "\n")
     }
     return nil
}

func main() {
    flag.Parse()

    if infile != nil {
        fmt.Println("infile = ", *infile, "outfile = ", *outfile, "algorithm = ", *algorithm);
    }
    values, err := readValues(*infile)

    if err == nil {
        fmt.Println("Read values:", values);
    } else {
        fmt.Println(err);
    }

    t1 := time.Now()
    if *algorithm == "qsort" {
        qsort.QuickSort(values)
    } else if *algorithm == "bubblesort" {
        bubblesort.BubbleSort(values)
    } else {
        fmt.Println("error argument");
        return
    }
    t2 := time.Now()
    fmt.Println("The sorting spend ", t2.Sub(t1), " to complete");

    err = writeValues(values, "outfile")
    if err != nil {
        fmt.Println("write error");
    } else {
        fmt.Println("write success");
    }
}
